'use strict';

const Service = require('egg').Service;

class UserService extends Service {
  async bet(arg) { // 加注
    const { app, ctx } = this;
    const room = await app.mysql.get('room', { roomnum: arg.roomNum });
    const user = await app.mysql.get('user', { username: arg.userName });
    const active = room.active.split('|');
    const max = room.max || 0;
    const call = max + arg.price;// 总额为房间最大下注额加自身加注
    user.bet += call;
    user.balance -= call;
    room.jackpot += call;
    room.max = call;
    room.at += 1;// 将光标下移一位
    if (!room.small) { // 如果是小盲注
      room.small = arg.price;
    }
    if (room.at === active.length) {
      room.at = 0;
    }
    const at = active[room.at];
    const stake = { at, username: arg.userName, bet: user.bet };
    ctx.socket.emit('beton', stake);
    ctx.socket.in(arg.roomNum).emit('beton', stake);// 发送系统消息
    await app.mysql.update('room', room);
    await app.mysql.update('user', user);
  }

  async call(arg) { // 跟注
    const { app, ctx } = this;
    const room = await app.mysql.get('room', { roomnum: arg.roomNum });
    const user = await app.mysql.get('user', { username: arg.userName });
    const active = room.active.split('|');
    const socket = room.socket.split('|');
    const max = room.max || 0;
    let overs = false;
    let balance = 0;
    room.at += 1;
    if (room.at === active.length) {
      room.at = 0;
    }
    const at = active[room.at];
    const nextuser = await app.mysql.get('user', { username: at });
    if (!room.inning) { // 如果是下大盲注
      user.bet = max * 2;
      user.balance -= user.bet;
      room.jackpot += user.bet;
      room.max = user.bet;
      nextuser.bet *= 2;
    } else {
      balance = max - user.bet;
      user.balance -= balance;
      room.jackpot += balance;
      user.bet = max;
    }
    await app.mysql.update('user', user);
    if (nextuser.bet === room.max || !room.inning) { // 如果下家的下注额与最大下注额相等则标志一轮下注结束
      overs = true;// 清空玩家桌面下注额
      room.inning += 1;// 下一轮
      active.forEach(async e => { // 清空数据库中玩家下注额
        const user = await app.mysql.get('user', { username: e });
        user.bet = 0;
        await app.mysql.update('user', user);
      });
      switch (room.inning)
      {
        case 1:// 发底牌
          this.service.operation.deal(room, active, socket, arg);
          break;
        case 2:// 翻牌
          this.service.operation.draw(room, arg, 3);
          break;
        case 3:// 转牌
          this.service.operation.draw(room, arg, 1);
          break;
        case 4:// 河牌
          this.service.operation.draw(room, arg, 1);
          break;
        default:// 判定
          this.service.decide.win();
      }
    }
    const stake = { jackpot: room.jackpot, at, username: arg.userName, bet: user.bet, overs };
    ctx.socket.emit('beton', stake);
    ctx.socket.in(arg.roomNum).emit('beton', stake);// 发送系统消息
    await app.mysql.update('room', room);// 更新数据库
  }

  async discard(arg) {
    const { app, ctx } = this;
    const room = await app.mysql.get('room', { roomnum: arg.roomNum });
    const user = await app.mysql.get('user', { username: arg.userName });
    const active = room.active.split('|');
    active.forEach((e, i) => {
      if (e === arg.userName) {
        active.splice(i, 1);
      }
    });
    if (room.at >= active.length) {
      room.at = 0;
    }
    if (active.length === 1) {
      const nextuser = await app.mysql.get('user', { username: active });
      nextuser.bet = 0;
      nextuser.balance += room.jackpot;
      console.log(`${active[0]}赢了`);
    } else {
      user.bet = 0;
      const at = active[room.at];
      const stake = { at, username: arg.userName, bet: user.bet, discard: true };
      ctx.socket.emit('beton', stake);
      ctx.socket.in(arg.roomNum).emit('beton', stake);// 发送系统消息
      room.active = active.join('|');
      await app.mysql.update('room', room);// 更新数据库
    }
  }

  async player(active) { // 更新所有玩家余额
    const userArr = [];
    return new Promise(res => {
      active.forEach(async (e, i) => {
        const user = await this.app.mysql.get('user', { username: e });
        const userObj = { username: user.username, balance: user.balance };
        userArr.push(userObj);
        if (i === active.length - 1) {
          res(userArr);
        }
      });
    });
  }

  async down(app, arr, username) {
    const user = await app.mysql.get('user', { username });
    console.log(user);
    user.poker = arr.join(',');
    await app.mysql.update('user', user);
  }

  async deal(room, active, socket, arg) { // 发底牌
    const { app, ctx } = this;
    const poker = [];
    for (let i = 1; i <= 52; i++) {
      poker.push(i);
    }
    socket.forEach(async (id, i) => {
      const arr = [];
      for (let i = 0; i < 2; i++) {
        const math = Math.floor(Math.random() * poker.length + 1);
        arr.push(poker.splice(math, 1)[0]);
      }
      console.log(active[i]);
      ctx.socket.emit(id, arr);
      ctx.socket.in(arg.roomNum).emit(id, arr);
      this.service.operation.down(app, arr, active[i]);
      // const user = await app.mysql.get('user', { username: active[i] });
      // user.poker = arr.toString();
      // await app.mysql.update('user', user);
    });
    room.poker = poker.toString();
    await app.mysql.update('room', room);
  }

  async draw(room, arg, n) { // 发公共牌
    const { app, ctx } = this;
    const poker = room.poker.split(',');
    const arr = [];
    let common = [];
    if (room.common) {
      common = room.common.split(',');
    }
    for (let i = 0; i < n; i++) {
      const math = Math.floor(Math.random() * (poker.length + 1));
      const num = Number(poker.splice(math, 1)[0]);
      arr.push(num); common.push(num);
    }
    ctx.socket.emit('draw', arr);
    ctx.socket.in(arg.roomNum).emit('draw', arr);
    room.poker = poker.toString();
    room.common = common.toString();
    await app.mysql.update('room', room);
  }
}

module.exports = UserService;
